package msgqueue

import (
	"container/list"
	"errors"
	"sync"
)

var (
	Err_QueueIsNil   = errors.New("queue list is nil")
	Err_QueueIsEmpty = errors.New("queue is empty")
)

type QueueType int

const (
	QueueType_FIFO QueueType = iota
)

type MsgQueue struct {
	lock      *sync.Mutex
	queue     *list.List
	queueType QueueType
}

func (this *MsgQueue) Push(msg interface{}) error {
	this.lock.Lock()
	defer this.lock.Unlock()
	if this.queue == nil {
		this.queue = list.New()
	}
	this.queue.PushBack(msg)
	return nil
}

func (this *MsgQueue) Pop() (interface{}, error) {
	if this.queue == nil {
		return nil, Err_QueueIsNil
	}
	if this.queue.Len() == 0 {
		return nil, Err_QueueIsEmpty
	}
	this.lock.Lock()
	defer this.lock.Unlock()
	var msg interface{}
	switch this.queueType {
	case QueueType_FIFO:
		elm := this.queue.Front()
		msg = this.queue.Remove(elm)
	}
	return msg, nil
}

func (this *MsgQueue) Count() int {
	if this.queue == nil {
		return 0
	}
	return this.queue.Len()
}
